package com.jolink.omiis.wechat.message;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jolink.omiis.wechat.util.WeChatConfiguration;

/**
 * 
 * 会话管理Manager 后续会存放至Redis中
 * 
 * @author WangYanqing
 *
 */
public class SessionManager {

	private static SessionManager sm = null;
	long defaultTimeout1 = 6 * 60 * 1000;
	long defaultTimeout2 = 4 * 60 * 1000;// 客户短时间未回复
	long defaultTimeout3 = 4 * 60 * 1000;// 坐席超时提示，提示用户断开会话
	long defaultTimeout4 = 90 * 60 * 1000;// 坐席超时提示，提示用户断开会话

	private SessionManager() {

	}

	public static SessionManager getSessionManager() {
		if (sm == null) {
			synchronized (SessionManager.class) {
				if (sm == null) {
					sm = new SessionManager();
				}
			}
		}
		return sm;
	}

	private static Logger logger = LoggerFactory.getLogger(SessionManager.class);
	/**
	 * 用户会话缓存，用于检测超时 1、短时间未回复超时； 2、长时间未回复超时； 3、坐席未回复超时； 类型为timeoutType
	 * key：openId { openId、 agent_previous_message_timestamp、
	 * customer_previous_message_timestamp、direction（agent、customer）
	 * 
	 * }
	 */
	private static Map<String, Map<String, String>> usersSessionMap = new ConcurrentHashMap<String, Map<String, String>>();

	public void removeSession(String openId) {
		if (StringUtils.isEmpty(openId))
			return;
		synchronized (usersSessionMap) {
			if (!usersSessionMap.containsKey(openId))
				return;
			logger.info("清除微信用户：{}会话记录，信息：{}毫秒。", openId, usersSessionMap.remove(openId));
		}
	}

	/**
	 * 将微信用户的会话信息放入缓存中，如果不存在添加，存在更新；
	 * 
	 * @param openId
	 * @param deltaSessionInfo
	 */
	public void updateSession(String openId, Map<String, String> deltaSessionInfo) {
		if (StringUtils.isEmpty(openId) || deltaSessionInfo.isEmpty())
			return;
		synchronized (usersSessionMap) {
			if (!usersSessionMap.containsKey(openId)) {
				logger.info("初始化微信用户：{}，发送时间信息：{}。", openId, deltaSessionInfo);
				if (deltaSessionInfo.size() != 5) {
					throw new RuntimeException("初始化微信用户会话信息不正确！");
				}
				usersSessionMap.put(openId, new HashMap<String, String>());
			}
			Map<String, String> userSession = usersSessionMap.get(openId);
			logger.info("更新微信用户：{}，发送时间信息：{}，更新内容：{}。", openId, userSession, deltaSessionInfo, usersSessionMap.size(),
					usersSessionMap);
			String oldDirection = userSession.get("direction");
			String newDirection = deltaSessionInfo.get("direction");
			if (!userSession.isEmpty()) {
				if (!oldDirection.equals(newDirection)) {
					if ("customer".equals(newDirection)) {
						userSession.put("agent_previous_message_timestamp",
								deltaSessionInfo.get("customer_previous_message_timestamp"));
					} else {
						userSession.put("customer_previous_message_timestamp",
								deltaSessionInfo.get("agent_previous_message_timestamp"));
					}
				}
			}

			userSession.putAll(deltaSessionInfo);
			if (userSession.size() != 5) {
				throw new RuntimeException("Session大小不正确！");
			}
			logger.info("更新微信用户：{}，发送时间信息：{}，更新内容：{}，当前会话总量：{}，详情：{}。", openId, userSession, deltaSessionInfo,
					usersSessionMap.size(), usersSessionMap);
		}
	}

	/**
	 * 2-短时间内未回复 1-达到超时阀值
	 * 
	 * @return
	 */
	public Map<String, String> getTimeoutSessionList() {
		logger.info("获取微信超时列表，当前会话总量：{}，详情：{}。", usersSessionMap.size(), usersSessionMap);
		Map<String, String> timeoutSessions = new HashMap<String, String>();
		synchronized (usersSessionMap) {
			for (Iterator<Entry<String, Map<String, String>>> it = usersSessionMap.entrySet().iterator(); it
					.hasNext();) {
				Entry<String, Map<String, String>> entry = it.next();
				String key = entry.getKey();
				Map<String, String> userSession = entry.getValue();
				logger.info("定时检查微信用户：{}是否超时，信息：{}。", key, userSession);
				String direction = userSession.get("direction");
				long timeout1 = WeChatConfiguration.getIngleton().getLong("TIMEOUT1", defaultTimeout1);// 客户超时
				long timeout2 = WeChatConfiguration.getIngleton().getLong("TIMEOUT2", defaultTimeout2);// 客户短时间未回复
				long timeout3 = WeChatConfiguration.getIngleton().getLong("TIMEOUT3", defaultTimeout3);// 坐席超时提示，提示用户断开会话
				long timeout4 = WeChatConfiguration.getIngleton().getLong("TIMEOUT4", defaultTimeout4);// 坐席超时提示，提示用户断开会话
				if ("agent".equals(direction)) {
					try {
						long customer_previous_message_timestamp = Long
								.parseLong(userSession.get("customer_previous_message_timestamp"));
						long currentTimestamp = System.currentTimeMillis();
						long diff = currentTimestamp - customer_previous_message_timestamp;

						logger.info("微信用户：{}，发送时间信息：{}，上次回复时间：{}，当前时间：{}，截止到现在未发送信息间隔：{}毫秒。", key, userSession,
								customer_previous_message_timestamp, currentTimestamp, diff);
						if (diff >= timeout1) {
							logger.info("微信用户：{}，已达到超时阀值：{}。", key, diff);
							usersSessionMap.remove(key);
							timeoutSessions.put(key, "1");
						} else if (diff >= timeout2 && diff <= (timeout2 + 30 * 1000)) {
							timeoutSessions.put(key, "2");
							logger.info("微信用户：{}，发送时间信息：{}，已达到短时间未回复阀值：{}。", key, userSession, diff);
						}
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
					}
				} else if ("customer".equals(direction)) {
					try {
						long customer_previous_message_timestamp = Long
								.parseLong(userSession.get("agent_previous_message_timestamp"));
						long currentTimestamp = System.currentTimeMillis();
						long diff = currentTimestamp - customer_previous_message_timestamp;
						logger.info("微信用户：{}，发送时间信息：{}，上次回复时间：{}，当前时间：{}，截止到现在坐席未发送信息间隔：{}毫秒。", key, userSession,
								customer_previous_message_timestamp, currentTimestamp, diff);
						if (diff >= timeout3 && diff <= (timeout3 + 30 * 1000)) {
							timeoutSessions.put(key, "3");
							logger.info("微信用户：{}，发送时间信息：{}，已达到坐席未发送时间阀值：{}。", key, userSession, diff);
							continue;
						}
						if (diff >= timeout4) {
							logger.info("座席端发生异常，没有正常结束会话，微信用户：{}，发送时间信息：{}，已达到坐席未发送时间阀值：{}，认定为超时会话，清除该会话。", key,
									userSession, diff);
						}

					} catch (Exception e) {
						logger.error(e.getMessage(), e);
					}
				}
			}
		}
		logger.info("超时的微信用户会话列表：{}。", timeoutSessions);
		return timeoutSessions;
	}
}
